package com.fare.taluo.helper;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.hadoop.hbase.filter.Filter;

import com.dayatang.domain.InstanceFactory;
import com.fare.taluo.db.hbase.HBaseCellModel;
import com.fare.taluo.db.hbase.HBaseRowModel;
import com.fare.taluo.db.hbase.HbaseManager;
import com.fare.taluo.vo.airfreight.StopOverEntityVO;
import com.fare.taluo.vo.airfreight.doub.CabinRelationEntityVO;
import com.fare.taluo.vo.core.AgentInfo;
import com.fare.taluo.vo.core.CabinEntityVO;
import com.fare.taluo.vo.core.HBaseFilterVO;
import com.fare.taluo.vo.core.PlaneInfo;
import com.fare.taluo.vo.core.TransitchangeEntityVO;

public class HbaseCustom {
	public static final String FAMILY_TYPE_ALL = null;
	/**
	 * 去程列簇
	 */
	public static final List<HBaseFilterVO> PLANE_INFO ;
	/**
	 * 去程舱位列簇
	 */
	public static final List<HBaseFilterVO> CABINS_INFO ;
	/**
	 * 返程经停列簇
	 */
	public static final List<HBaseFilterVO>  RETURN_STOPOVER_INFO ;
	/**
	 * 返程中转列簇
	 */
	public static final List<HBaseFilterVO>  RETURN_TRANSIT_INFO ;
	/**
	 * 返程舱位列簇
	 */
	public static final List<HBaseFilterVO>  RETURN_CABIN_INFO ;
	/**
	 * 返程代理列簇
	 */
	public static final List<HBaseFilterVO>   RETURN_AGENT_INFO;
	
	public static final String LP_LINE_DAY = "LP_LINE_DAY";
	public static final String LP_LINE_HOUR = "LP_LINE_HOUR";
	public static final String CRAWL_PLANE_FREIGHT = "CRAWL_PLANE_FREIGHT";
	public static final String CRAWL_PLANE_FREIGHT_DOUBLE = "CRAWL_PLANE_FREIGHT_DOUBLE";
	public static final String LP_FLIGHT = "LP_FLIGHT";
	public static final String LP_FLIGHT_DATE = "LP_FLIGHT_DATE";
	public static final String LP_FLIGHT_DOUBLE = "LP_FLIGHT_DOUBLE";
	public static final String LP_FLIGHT_HISTORY = "LP_FLIGHT_HISTORY";
	public static final String LP_FLIGHT_HISTORY_DOUBLE = "LP_FLIGHT_HISTORY_DOUBLE";
	public static final String LP_FLIGHT_OFFICIAL_CHANNEL_PLUS_DAY = "LP_FLIGHT_OFFICIAL_CHANNEL_PLUS_DAY";
	public static final String LP_FLIGHT_OFFICIAL_CHANNEL_PLUS_TOP5 = "LP_FLIGHT_OFFICIAL_CHANNEL_PLUS_TOP5";
	
	private static Map<String,Method> planeInfoMethods = new HashMap<String, Method>();
	private static Map<String,Method> agentMethods = new HashMap<String, Method>(); 
	private static Map<String,Method> cabinMethods = new HashMap<String, Method>(); 
	private static Map<String,Method> stopOverMethods = new HashMap<String, Method>(); 
	private static Map<String,Method> transitMethods = new HashMap<String, Method>(); 
	private static Map<String,Method> cabinRelationMethods = new HashMap<String, Method>();
	
	static{
		Method[] planeInfoMs = PlaneInfo.class.getMethods();
		for (Method m : planeInfoMs) {
			planeInfoMethods.put(m.getName(), m);
		}
		Method[] agentMs = AgentInfo.class.getMethods();
		for (Method m : agentMs) {
			agentMethods.put(m.getName(), m);
		}
		Method[] cabinMs = CabinEntityVO.class.getMethods();
		for (Method m : cabinMs) {
			cabinMethods.put(m.getName(), m);
		}
		Method[] stopOverMs = StopOverEntityVO.class.getMethods();
		for (Method m : stopOverMs) {
			stopOverMethods.put(m.getName(), m);
		}
		Method[] transitMs = TransitchangeEntityVO.class.getMethods();
		for (Method m : transitMs) {
			transitMethods.put(m.getName(), m);
		}
		Method[] cabinRelationMs = CabinRelationEntityVO.class.getMethods();
		for (Method m : cabinRelationMs) {
			cabinRelationMethods.put(m.getName(), m);
		}
		
		PLANE_INFO = new ArrayList<HBaseFilterVO>();
		PLANE_INFO.add(new HBaseFilterVO("planeinfo",null));
		
		CABINS_INFO  = new ArrayList<HBaseFilterVO>();
		CABINS_INFO.add(new HBaseFilterVO("cabinsInfo",null));
		
		RETURN_STOPOVER_INFO = new ArrayList<HBaseFilterVO>();
		RETURN_STOPOVER_INFO.add(new HBaseFilterVO("returnStopoverInfo",null));
		
		RETURN_TRANSIT_INFO = new ArrayList<HBaseFilterVO>();
		RETURN_TRANSIT_INFO.add(new HBaseFilterVO("returnTransitInfo",null));
		
		RETURN_CABIN_INFO = new ArrayList<HBaseFilterVO>();
		RETURN_CABIN_INFO.add(new HBaseFilterVO("returnCabinInfo",null));
		
		RETURN_AGENT_INFO = new ArrayList<HBaseFilterVO>();
		RETURN_AGENT_INFO.add(new HBaseFilterVO("returnAgentInfo",null));
		
	}
	
	
	/**
	 * 根据表名、开始及结束rowkey获得数据集
	 * @param tableName 表名 不可为空
	 * @param startRowKey 开始rowkey 不可为空
	 * @param endRowKey 结束rowkey 不可为空
	 * @return
	 * @throws Exception 
	 */
	 public static List<PlaneInfo> findByConditionsToPlaneInfo(String tableName,
				String startRowKey, String endRowKey) throws Exception{
		 return findByConditionsToPlaneInfo(tableName,
					 startRowKey,  endRowKey,null ,
					null);
	 }
	 
	 /**
	  * 根据hbase自带过滤器，进行数据过滤,获得数据集
	  * @param tableName  表名 不可为空
	  * @param startRowKey 开始rowkey 不可为空
	  * @param endRowKey 结束rowkey 不可为空
	  * @param filterList hbase自带过滤器
	  * @return
	 * @throws Exception 
	  */
	 public static List<PlaneInfo> findByConditionsToPlaneInfo(String tableName,
				String startRowKey, String endRowKey,
				List<Filter> filterList) throws Exception{
		 return findByConditionsToPlaneInfo( tableName,
					 startRowKey,  endRowKey, null,
					 filterList);
	 }
	
	public static PlaneInfo findUniqueToPlaneInfo(String tableName, String rowKey) throws Exception{
		HbaseManager hbaseManager = InstanceFactory.getInstance(HbaseManager.class);
		HBaseRowModel model = hbaseManager.getOneRecord(tableName, rowKey);
		return convertPlaneInfo(model);
	}
	/**
	 * 根据多个条件查询
	 * @param tableName 表名 不可为空
	 * @param startRowKey 开始rowkey 不可为空
	 * @param endRowKey 结束rowkey 不可为空
	 * @param voList 过滤列簇或列 可以为空
	 * @param filterList hbase自带过滤器 可以为空
	 * @return
	 * @throws Exception 
	 */
	 public static List<PlaneInfo> findByConditionsToPlaneInfo(String tableName,
				String startRowKey, String endRowKey, List<HBaseFilterVO> voList,
				List<Filter> filterList) throws Exception{
			 HbaseManager hbaseManager = InstanceFactory.getInstance(HbaseManager.class);
			 	//获得多个HBaseRowModel,HBaseRowModel相当于一行
				List<HBaseRowModel> list = hbaseManager.getMultRecordByConditions(tableName, startRowKey, endRowKey, voList, filterList);
				List<PlaneInfo> result = new ArrayList<PlaneInfo>();
				//循环组装对象，获得planeInfo列表
				for (HBaseRowModel model : list) {
					result.add(convertPlaneInfo(model));
				}
				
				return result; 
		}
	 /**
	  * 将hbase键值对转换为planeInfo对象
	  * @param model
	  * @return
	  */
	 private static PlaneInfo convertPlaneInfo(HBaseRowModel model){
			String qualifier,value,family;
			String[] agentInfoKey;
			String[] cabinInfoKey;
			String[] stopOverInfoKey;
			String[] transitsInfoKey;
		//获得去程代理商
			List<AgentInfo> agents = new ArrayList<AgentInfo>();
			Map<String,AgentInfo> agentMap = new HashMap<String, AgentInfo>();
			
			//获得去程舱位
			List<CabinEntityVO> cabins = new ArrayList<CabinEntityVO>();
			Map<String,CabinEntityVO> cabinsMap = new HashMap<String, CabinEntityVO>();
			
			//获得去程经停城市
			List<StopOverEntityVO> stopOverEntityVOs = new ArrayList<StopOverEntityVO>();
			Map<String,StopOverEntityVO> stopOverEntityMap = new HashMap<String, StopOverEntityVO>();
			
			//获得去程中转
			List<TransitchangeEntityVO> transitEntityVOs = new ArrayList<TransitchangeEntityVO>();
			Map<String,TransitchangeEntityVO> transitchangeEntityMap = new HashMap<String, TransitchangeEntityVO>();
			
			//获得舱位关系
			List<CabinRelationEntityVO> cabinRelationEntityVOs = new ArrayList<CabinRelationEntityVO>();
			Map<String,CabinRelationEntityVO> cabinRelationEntityMap = new HashMap<String, CabinRelationEntityVO>();
			
			
			 Map<String,PlaneInfo> returnPlaneInfoMap = new HashMap<String, PlaneInfo>();
			 Map<String,CabinEntityVO> returnCabinMap = new HashMap<String,CabinEntityVO>();
			 Map<String,StopOverEntityVO> returnStopOverMap = new HashMap<String, StopOverEntityVO>();
			 Map<String,TransitchangeEntityVO> returnTransitMap = new HashMap<String, TransitchangeEntityVO>();
			 Map<String,AgentInfo> returnAgentInfoMap = new HashMap<String, AgentInfo>();
			
			
			PlaneInfo planeInfo = new PlaneInfo();

			try {
				//组装数据为planeinfo对象
				for (HBaseCellModel cell : model.getCells()) {
					 qualifier = new String(cell.getQualifier().getBytes(),"utf-8");
					 family = new String(cell.getFamily().getBytes(),"utf-8");
					 value = new String(cell.getValue().getBytes(), "utf-8");
					if ("planeinfo".equals(family)) {
						Method method = planeInfoMethods.get("set" + qualifier.substring(0, 1).toUpperCase()+ qualifier.substring(1));
						if(null != method){
							try{
								method.invoke(planeInfo, value);
							} catch (Exception e) {
								e.printStackTrace();
							}
						}
					}else if ("agentInfos".equals(family)) {
						agentInfoKey = cell.getQualifier().split("_");
						String property = agentInfoKey[0];
						String str = agentInfoKey[1];
						Method method = agentMethods.get("set"+ property.substring(0, 1)
								.toUpperCase()+ property.substring(1));
						if (null != method) {
							if (!agentMap.containsKey(str)) {
								agentMap.put(str, new AgentInfo());
							}
							if (agentMap.keySet().contains(str)) 
								try{
									method.invoke(agentMap.get(str),cell.getValue());
								} catch (Exception e) {
									e.printStackTrace();
								}
						}
					}else if("cabinsInfo".equals(family)){
						cabinInfoKey = cell.getQualifier().split("_");
						String property = cabinInfoKey[0];
						String number = cabinInfoKey[1];
						Method method = cabinMethods.get("set"+ property.substring(0, 1)
								.toUpperCase()+ property.substring(1));
						if (null != method) {
							if (!cabinsMap.containsKey(number)) {
								cabinsMap.put(number, new CabinEntityVO());
							}
							if (cabinsMap.keySet().contains(number)) 
								try{
									if(property!=null && property.indexOf("price")!=-1){
										method.invoke(cabinsMap.get(number),cell.getValue()==null?0.0:Double.parseDouble(cell.getValue()));
									}else{
										method.invoke(cabinsMap.get(number),cell.getValue());
										
									}
									
								} catch (Exception e) {
									e.printStackTrace();
								}
						}
						
					}else if("stopOversInfo".equals(family)){
						stopOverInfoKey = cell.getQualifier().split("_");
						String property = stopOverInfoKey[0];
						String number = stopOverInfoKey[1];
						Method method = stopOverMethods.get("set"+ property.substring(0, 1)
								.toUpperCase()+ property.substring(1));
						if (null != method) {
							if (!stopOverEntityMap.containsKey(number)) {
								stopOverEntityMap.put(number, new StopOverEntityVO());
							}
							if (stopOverEntityMap.keySet().contains(number)) 
								try{
									method.invoke(stopOverEntityMap.get(number),cell.getValue());
								} catch (Exception e) {
									e.printStackTrace();
								}
						}
					}else if("transitsInfo".equals(family)){
						transitsInfoKey = cell.getQualifier().split("_");
						String property = transitsInfoKey[0];
						String number = transitsInfoKey[1];
						Method method = transitMethods.get("set"+ property.substring(0, 1)
								.toUpperCase()+ property.substring(1));
						if (null != method) {
							if (!transitchangeEntityMap.containsKey(number)) {
								transitchangeEntityMap.put(number, new TransitchangeEntityVO());
							}
							if (transitchangeEntityMap.keySet().contains(number)) 
								try{
									method.invoke(transitchangeEntityMap.get(number),cell.getValue());
								} catch (Exception e) {
									e.printStackTrace();
								}
						}
					}else if("returnPlaneInfosInfo".equals(family)){//若有返程航班，则生成返程航班保存到map中，key为
						String[] returnFamilyInfo = cell.getQualifier().split("_");
						String property = returnFamilyInfo[0];
						String number = returnFamilyInfo[1];
						Method method = planeInfoMethods.get("set"+ property.substring(0, 1)
								.toUpperCase()+ property.substring(1));
						if (null != method) {
							if (!returnPlaneInfoMap.containsKey(number)) {
								returnPlaneInfoMap.put(number, new PlaneInfo());
							}
							if (returnPlaneInfoMap.keySet().contains(number)) 
								try{
									method.invoke(returnPlaneInfoMap.get(number),cell.getValue());
								} catch (Exception e) {
									e.printStackTrace();
								}
						}
						
					}else if("returnAgentsInfo".equals(family)){//若有返程航班，则生成返程航班保存到map中，key为
						String[] returnFamilyInfo = cell.getQualifier().split("_");
						String property = returnFamilyInfo[0];
						String parentNum = returnFamilyInfo[1];
						String agentNum = returnFamilyInfo[2]; 
						Method method = agentMethods.get("set"+ property.substring(0, 1)
								.toUpperCase()+ property.substring(1));
						if (null != method) {
							if (!returnAgentInfoMap.containsKey(parentNum+"_"+agentNum)) {
								returnAgentInfoMap.put(parentNum+"_"+agentNum, new AgentInfo());
							}
							if (returnAgentInfoMap.keySet().contains(parentNum+"_"+agentNum)) 
								try{
									method.invoke(returnAgentInfoMap.get(parentNum+"_"+agentNum),cell.getValue());
								} catch (Exception e) {
									e.printStackTrace();
								}
						}
						
					}else if("returnCabinsInfo".equals(family)){//若有返程航班，则生成返程航班保存到map中，key为
						String[] returnFamilyInfo = cell.getQualifier().split("_");
						String property = returnFamilyInfo[0];
						String parentNum = returnFamilyInfo[1];
						String cabinNum = returnFamilyInfo[2]; 
						Method method = cabinMethods.get("set"+ property.substring(0, 1)
								.toUpperCase()+ property.substring(1));
						if (null != method) {
							if (!returnCabinMap.containsKey(parentNum+"_"+cabinNum)) {
								returnCabinMap.put(parentNum+"_"+cabinNum, new CabinEntityVO());
							}
							if (returnCabinMap.keySet().contains(parentNum+"_"+cabinNum)) 
								try{
									if(property!=null && property.indexOf("price")!=-1){
										method.invoke(returnCabinMap.get(parentNum+"_"+cabinNum),cell.getValue()==null?null:Double.parseDouble(cell.getValue()));
									}else{
										method.invoke(returnCabinMap.get(parentNum+"_"+cabinNum),cell.getValue());
									}
									
								} catch (Exception e) {
									e.printStackTrace();
								}
						}
						
					}else if("returnStopOversInfo".equals(family)){//若有返程航班，则生成返程航班保存到map中，key为
						String[] returnFamilyInfo = cell.getQualifier().split("_");
						String property = returnFamilyInfo[0];
						String parentNum = returnFamilyInfo[1];
						String stopOverNum = returnFamilyInfo[2]; 
						Method method = stopOverMethods.get("set"+ property.substring(0, 1)
								.toUpperCase()+ property.substring(1));
						if (null != method) {
							if (!returnCabinMap.containsKey(parentNum+"_"+stopOverNum)) {
								returnStopOverMap.put(parentNum+"_"+stopOverNum, new StopOverEntityVO());
							}
							if (returnStopOverMap.keySet().contains(parentNum+"_"+stopOverNum)) 
								try{
									method.invoke(returnStopOverMap.get(parentNum+"_"+stopOverNum),cell.getValue());
								} catch (Exception e) {
									e.printStackTrace();
								}
						}
						
					}else if("returnTransitsInfo".equals(family)){//若有返程航班，则生成返程航班保存到map中
						String[] returnFamilyInfo = cell.getQualifier().split("_");
						String property = returnFamilyInfo[0];
						String parentNum = returnFamilyInfo[1];
						String transitNum = returnFamilyInfo[2]; 
						Method method = transitMethods.get("set"+ property.substring(0, 1)
								.toUpperCase()+ property.substring(1));
						if (null != method) {
							if (!returnTransitMap.containsKey(parentNum+"_"+transitNum)) {
								returnTransitMap.put(parentNum+"_"+transitNum, new TransitchangeEntityVO());
							}
							if (returnTransitMap.keySet().contains(parentNum+"_"+transitNum)) 
								try{
									method.invoke(returnTransitMap.get(parentNum+"_"+transitNum),cell.getValue());
								} catch (Exception e) {
									e.printStackTrace();
								}
						}
						
					}else if("cabinRelationsInfo".equals(family)){//若有返程航班，则生成返程航班保存到map中
						String[] cabinRelationsInfo = cell.getQualifier().split("_");
						String property = cabinRelationsInfo[0];
						String number = cabinRelationsInfo[1];
						Method method = cabinRelationMethods.get("set"+ property.substring(0, 1)
								.toUpperCase()+ property.substring(1));
						if (null != method) {
							if (!cabinRelationEntityMap.containsKey(number)) {
								cabinRelationEntityMap.put(number, new CabinRelationEntityVO());
							}
							if (cabinRelationEntityMap.keySet().contains(number)) 
								try{
										method.invoke(cabinRelationEntityMap.get(number),cell.getValue());
								} catch (Exception e) {
									e.printStackTrace();
								}
						}
						
					}
				}
				
				agents.addAll(agentMap.values());
				cabins.addAll(cabinsMap.values());
				stopOverEntityVOs.addAll(stopOverEntityMap.values());
				transitEntityVOs.addAll(transitchangeEntityMap.values());	
				cabinRelationEntityVOs.addAll(cabinRelationEntityMap.values());
				
				
				//组织去程信息
				planeInfo.setAgentInfos(agents);
				planeInfo.setCabins(cabins);
				
				planeInfo.setTransit(transitEntityVOs);
				planeInfo.setStopOverlist(stopOverEntityVOs);
				planeInfo.setCabinRelations(cabinRelationEntityVOs);
				
				
				//组织返程航班信息
				if(returnPlaneInfoMap != null && returnPlaneInfoMap.size() > 0){
					List<PlaneInfo> returnPlaneInfo = getReturnPlaneInfo(returnPlaneInfoMap,returnCabinMap,returnStopOverMap,returnTransitMap,returnAgentInfoMap);
					planeInfo.setReturnPlaneInfo(returnPlaneInfo);
				}	

			} catch (Exception e) {
				e.printStackTrace();
			}finally{
				qualifier = null;
				value = null;
				family = null;
				agentInfoKey = null;
				cabinInfoKey = null;
				stopOverInfoKey = null;
				transitsInfoKey = null;
			//获得去程代理商
				agents = null;
				agentMap = null;
				
				//获得去程舱位
				cabins = null;
				cabinsMap = null;
				
				//获得去程经停城市
				stopOverEntityVOs = null;
				stopOverEntityMap  = null;
				
				//获得去程中转
				transitEntityVOs  = null;
				transitchangeEntityMap = null;
				
				//获得舱位关系
				cabinRelationEntityVOs  = null;
				cabinRelationEntityMap  = null;
				
				
				 returnPlaneInfoMap  = null;
				 returnCabinMap  = null;
				 returnStopOverMap  = null;
				 returnTransitMap  = null;
				 returnAgentInfoMap  = null;
			}
			return planeInfo;
	 }
	 private static List<PlaneInfo>  getReturnPlaneInfo(Map<String,PlaneInfo> returnPlaneInfoMap,  Map<String,CabinEntityVO> returnCabinMap, Map<String,StopOverEntityVO> returnStopOverMap, Map<String,TransitchangeEntityVO> returnTransitMap, Map<String,AgentInfo> returnAgentInfoMap){
			if (returnCabinMap != null && returnCabinMap.size() > 0) {
				for (String key : returnCabinMap.keySet()) {
					returnPlaneInfoMap.get(key.split("_")[0]).getCabins()
							.add(returnCabinMap.get(key));
				}
			}

			if (returnStopOverMap != null && returnStopOverMap.size() > 0) {
				for (String key : returnStopOverMap.keySet()) {
					returnPlaneInfoMap.get(key.split("_")[0]).getStopOverlist()
							.add(returnStopOverMap.get(key));
				}
			}

			if (returnTransitMap != null && returnTransitMap.size() > 0) {
				for (String key : returnTransitMap.keySet()) {
					returnPlaneInfoMap.get(key.split("_")[0]).getTransit()
							.add(returnTransitMap.get(key));
				}
			}

			if (returnAgentInfoMap != null && returnAgentInfoMap.size() > 0) {

				for (String key : returnAgentInfoMap.keySet()) {
					returnPlaneInfoMap.get(key.split("_")[0]).getAgentInfos()
							.add(returnAgentInfoMap.get(key));
				}
			}

			List<PlaneInfo> returnList = new ArrayList<PlaneInfo>();
			returnList.addAll(returnPlaneInfoMap.values());
			return returnList;
		}
	 public static void main(String[] args) throws Exception {
		 List<PlaneInfo> list = HbaseCustom.findByConditionsToPlaneInfo("LP_FLIGHT_DOUBLE", "000000000000000000000000000000000000000000000000000", "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", null, null);
		 System.out.println(list.size());
	}
}
